using System;
using System.Collections.Generic;
using System.Text;
using Forecast.Database;
using NUnit.Framework;

namespace Forecast.Business.Test
{
    [TestFixture]
    public class TestRemoveOffer
    {
        #region Variables

        private RemoveOffer _removeOffer;
        private Offer _offer;
        private Player _player;
        private Holding _holding;
        private Prediction _prediction;

        #endregion
        #region Setup / Teardown

        [SetUp]
        public void Init()
        {
            _removeOffer = new RemoveOffer();
            _player = Mocks.GetBuyer();
            _offer = Mocks.GetBuyOffer();
            _holding = Mocks.GetBuyerHolding();
            _prediction = Mocks.GetPrediction();
        }

        #endregion
        #region Tests for Buy

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void NullOffer()
        {
            _removeOffer.Execute(null, _player, _holding, _prediction);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void NullPlayer()
        {
            _removeOffer.Execute(_offer, null, _holding, _prediction);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void PlayerDoesNotOwnHolding()
        {
            _player.Id = 999;
            _removeOffer.Execute(_offer, _player, _holding, _prediction);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void PredictionInOfferAndHoldingDoesNotMatch()
        {
            _offer.PredictionId = 999;
            _removeOffer.Execute(_offer, _player, _holding, _prediction);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void OfferDoesNotBelongToPlayer()
        {
            _offer.PlayerId = 999;
            _removeOffer.Execute(_offer, _player, _holding, _prediction);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void OfferIsAlreadyAccepted()
        {
            _offer.IsAccepted = true;
            _removeOffer.Execute(_offer, _player, _holding, _prediction);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void OfferIsExpired()
        {
            _offer.IsActive = false;
            _removeOffer.Execute(_offer, _player, _holding, _prediction);
        }

        [Test]
        public void BuyOfferRemoved()
        {
            _offer.IsBuy = true;
            _removeOffer.Execute(_offer, _player, _holding, _prediction);
            Assert.AreEqual(MockIds.BUYER_HOLDING, _removeOffer.RemoveOfferHolding.Id);
            Assert.AreEqual(10, _removeOffer.RemoveOfferHolding.NumPredictions);
            Assert.AreEqual(MockIds.BUYER, _removeOffer.RemoveOfferHolding.PlayerId);
            Assert.AreEqual(MockIds.PREDICTION, _removeOffer.RemoveOfferHolding.PredictionId);
            Assert.AreEqual(2100, _removeOffer.RemoveOfferPlayer.Cash);
            Assert.AreEqual(MockIds.BUYER, _removeOffer.RemoveOfferPlayer.Id);
            Assert.AreEqual("Jesus", _removeOffer.RemoveOfferPlayer.UserName);
            Assert.AreEqual(0, _removeOffer.RemoveOfferOffer.AcceptorId);
            Assert.AreEqual(DateTime.Today.AddDays(2), _removeOffer.RemoveOfferOffer.EndDate);
            Assert.AreEqual(MockIds.BUY_OFFER, _removeOffer.RemoveOfferOffer.Id);
            Assert.AreEqual(false, _removeOffer.RemoveOfferOffer.IsAccepted);
            Assert.AreEqual(false, _removeOffer.RemoveOfferOffer.IsActive);
            Assert.AreEqual(true, _removeOffer.RemoveOfferOffer.IsBuy);
            Assert.AreEqual(10, _removeOffer.RemoveOfferOffer.NumPredictions);
            Assert.AreEqual(MockIds.BUYER, _removeOffer.RemoveOfferOffer.PlayerId);
            Assert.AreEqual(MockIds.PREDICTION, _removeOffer.RemoveOfferOffer.PredictionId);
            Assert.AreEqual(60, _removeOffer.RemoveOfferOffer.Price);
        }

        [Test]
        public void BuyOfferRemovedWhenNoHolding()
        {
            _offer.IsBuy = true;
            _holding = null;
            _removeOffer.Execute(_offer, _player, _holding, _prediction);
            Assert.AreEqual(2100, _removeOffer.RemoveOfferPlayer.Cash);
            Assert.AreEqual(2100, _player.Cash);
        }

        [Test]
        public void SellOfferRemoved()
        {
            _offer.IsBuy = false;
            Offer sellOffer = Mocks.GetSellOffer();
            Player seller = Mocks.GetSeller();
            Holding sellerHolding = Mocks.GetSellerHolding();
            _removeOffer.Execute(sellOffer, seller, sellerHolding, _prediction);
            Assert.AreEqual(MockIds.SELLER_HOLDING, _removeOffer.RemoveOfferHolding.Id);
            Assert.AreEqual(90, _removeOffer.RemoveOfferHolding.NumPredictions);
            Assert.AreEqual(MockIds.SELLER, _removeOffer.RemoveOfferHolding.PlayerId);
            Assert.AreEqual(MockIds.PREDICTION, _removeOffer.RemoveOfferHolding.PredictionId);
            Assert.AreEqual(1500, _removeOffer.RemoveOfferPlayer.Cash);
            Assert.AreEqual(MockIds.SELLER, _removeOffer.RemoveOfferPlayer.Id);
            Assert.AreEqual("Beelzebub", _removeOffer.RemoveOfferPlayer.UserName);
            Assert.AreEqual(0, _removeOffer.RemoveOfferOffer.AcceptorId);
            Assert.AreEqual(DateTime.Today.AddDays(4), _removeOffer.RemoveOfferOffer.EndDate);
            Assert.AreEqual(MockIds.SELL_OFFER, _removeOffer.RemoveOfferOffer.Id);
            Assert.AreEqual(false, _removeOffer.RemoveOfferOffer.IsAccepted);
            Assert.AreEqual(false, _removeOffer.RemoveOfferOffer.IsActive);
            Assert.AreEqual(false, _removeOffer.RemoveOfferOffer.IsBuy);
            Assert.AreEqual(15, _removeOffer.RemoveOfferOffer.NumPredictions);
            Assert.AreEqual(MockIds.SELLER, _removeOffer.RemoveOfferOffer.PlayerId);
            Assert.AreEqual(MockIds.PREDICTION, _removeOffer.RemoveOfferOffer.PredictionId);
            Assert.AreEqual(59, _removeOffer.RemoveOfferOffer.Price);
        }

        #endregion
    }
}
